﻿

//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "CmdExportImportGRep.h"
#include "Box3d.h"
#include "IUiView.h"
#include "IElement.h"
#include "OwnerPtr.h"
#include "FilePath.h"
#include "IDocument.h"
#include "ElementId.h"
#include "IModelView.h"
#include "IUiDocument.h"
#include "FileUtility.h"
#include "IGraphicsNode.h"
#include "GbmpFileSystem.h"
#include "IGenericElement.h"
#include "GcmpCommandState.h"
#include "IUserTransaction.h"
#include "GraphicsNodeUtils.h"
#include "IElementModelShape.h"
#include "IPureGraphicsElement.h"
#include "IGraphicsElementShape.h"
#include "IGraphicsStyleManager.h"
#include "IUiDocumentViewManager.h"
#include "IElementBasicInformation.h"

#include "QSysInfo"
#include "json/value.h"
#include "QFileDialog.h"
#include "JsonUtility.h"
#include "GRepCommandIds.h"
#include "CommandRegister.h"
#include "CmdGRepModuleEntry.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 

using namespace gcmp;
using namespace Sample;

REGISTER_COMMAND(CmdExportGRep)

CmdExportGRep::CmdExportGRep()
    :CommandBase(ID_CMD_GREP_EXPORT)
{
}

bool CmdExportGRep::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdExportGRep::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

gcmp::OwnerPtr<gcmp::IAction> CmdExportGRep::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocViewMgr, L"获取UI文档视图管理器失败",L"GDMP",L"2024-03-30");
    IUiDocument* pUiDoc = pUiDocViewMgr->GetCurrentUiDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDoc, L"获取UI文档失败",L"GDMP",L"2024-03-30");
    IDocument* pDoc = pUiDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"获取文档失败",L"GDMP",L"2024-03-30");
    
    IUiView* pUiView = pUiDocViewMgr->GetCurrentUiView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiView, L"pUiView为空", L"GDMP", L"2024-03-30");
    IModelView* pModelView = pUiView->GetModelView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空", L"GDMP", L"2024-03-30");
    GraphicsElementShapes greps = pModelView->GetVisibleModelViewElementShapes();
    if (greps.size() == 0)
    {
        return nullptr;
    }

    QString qFolderPath = QFileDialog::getExistingDirectory(nullptr, QString::fromStdWString(L"选择文件夹"), "./", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (qFolderPath.isEmpty())
    {
        return nullptr;
    }

    std::wstring folderPath = qFolderPath.toStdWString();
    for (auto& it : greps)
    {
        OwnerPtr<IGraphicsElementShape> opGRep = TransferOwnershipQuickCast<IGraphicsElementShape>(it.second->Clone());
        if (opGRep == nullptr)
        {
            continue;
        }
        GraphicsNodeUtils::CleanGraphicsNodeStyleAndMaterial(pDoc, opGRep.get());
        const IElement* pElem = pDoc->GetElement(it.first);
        DBG_WARN_AND_CONTINUE_UNLESS(pElem, L"pElem为空", L"GDMP", L"2024-03-30");
        Json::Value jValue = it.second->ToJson(pElem);
        std::wstring jsonPath = FilePath::Combine(folderPath, StringUtil::ToWString(it.first.AsInt64()) + L".json");
        JsonUtility::SerializeToFile(jsonPath, jValue);
    }

    return nullptr;
}

REGISTER_COMMAND(CmdImportGRep)

CmdImportGRep::CmdImportGRep()
    :CommandBase(ID_CMD_GREP_IMPORT)
{
}

bool CmdImportGRep::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdImportGRep::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

gcmp::OwnerPtr<gcmp::IAction> CmdImportGRep::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocViewMgr, L"获取UI文档视图管理器失败",L"GDMP",L"2024-03-30");
    IUiDocument* pUiDoc = pUiDocViewMgr->GetCurrentUiDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDoc, L"获取UI文档失败",L"GDMP",L"2024-03-30");
    IDocument* pDoc = pUiDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"获取文档失败",L"GDMP",L"2024-03-30");

    IUiView* pUiView = pUiDocViewMgr->GetCurrentUiView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiView, L"pUiView为空", L"GDMP", L"2024-03-30");
    IModelView* pModelView = pUiView->GetModelView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空", L"GDMP", L"2024-03-30");
    GraphicsElementShapes greps = pModelView->GetVisibleModelViewElementShapes();
    if (greps.size() == 0)
    {
        return nullptr;
    }

    QString qFolderPath = QFileDialog::getExistingDirectory(nullptr, QString::fromStdWString(L"选择文件夹"), "./", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (qFolderPath.isEmpty())
    {
        return nullptr;
    }
    std::wstring folderPath = qFolderPath.toStdWString();

    std::vector<std::wstring> oFiles;
    FileSystem::GetSubFiles(folderPath, oFiles, false, true);
    if (oFiles.size() == 0)
    {
        return nullptr;
    }

    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(pDoc, L"导入GRep");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opTransaction, L"opTransaction为空",L"GDMP",L"2024-03-30");
    for (auto file : oFiles)
    {
        FilePath filePath(file);
        if (filePath.GetExtension() != L".json")
        {
            continue;
        }
        std::string context = FileUtility::LoadINIFile(FilePath::Combine(folderPath, file));
        OwnerPtr<IGraphicsNode> opGNode = IGraphicsElementShape::CreateFromJson(context);

        OwnerPtr<IGraphicsElementShape> opGRep = TransferOwnershipQuickCast<IGraphicsElementShape>(opGNode);
        if (opGRep)
        {
            IPureGraphicsElement::Create(pDoc, TransferOwnership(opGRep));
        }
    }
    opTransaction->Commit();
    return nullptr;
}
